<?php

namespace App\Client;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use Slim\Views\PhpRenderer;

class HomeApp
{
    /**
     * Annotation combined with phpdoc:
     *
     * @Inject
     * @var PhpRenderer
     */
    public $phpRenderer;

    /**
     * Annotation combined with phpdoc:
     *
     * @Inject("settings")
     */
    public $settings;

    public $logger;

    public $total;
    public $query;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function home(Request $request, Response $response, $args): Response
    {
        $this->logger->info("Home start");
        $vars = $request->getQueryParams();
        $category = isset($vars['c']) && trim($vars['c']) ? $vars['c'] : '';
        $page = isset($vars['p']) && $vars['p'] ? $vars['p'] : 1;
        $query = $vars['kw'] ?? '';
        $link = '/?c=' . $category . '&q=' . $query;
        $limit = 12;
        if ($category || $query) $limit = 50;

        $this->category = $category;
        $this->query = $query;
        $main = $this->getMain($page, $limit);
        $data = [
            'header' => $this->phpRenderer->fetch('public/header.phtml'),
            'menu' => $this->phpRenderer->fetch('public/menu.phtml', ['query' => $query]),
            'main' => $main,
            'footer' => $this->phpRenderer->fetch('public/footer.phtml'),
        ];

        $data['category'] = $category;
        $data['query'] = $query;
        $data['pagination'] = $this->getPage($link, $this->total, $page, $limit);

        $html = $this->phpRenderer->fetch('home/index.phtml', ['data' => $data]);

        $body = $response->getBody();
        $body->write($html);
        return $response;
    }

    public function addPage(Request $request, Response $response, $args)
    {
        $data = [
            'header' => $this->phpRenderer->fetch('public/header.phtml'),
            'menu' => $this->phpRenderer->fetch('public/menu.phtml'),
            'main' => $this->phpRenderer->fetch('home/add-main.phtml'),
            'footer' => $this->phpRenderer->fetch('public/footer.phtml'),
        ];
        $html = $this->phpRenderer->fetch('home/add-index.phtml', ['data' => $data]);

        $body = $response->getBody();
        $body->write($html);
        return $response;
    }

    public function addSubmit(Request $request, Response $response, $args)
    {
        $return = '<h2 style="text-align:center;">添加失败，请检查表单信息，或联系管理员：727403273@qq.com</h2><h3 style="text-align: center;"><a href="/">返回</a></h3>';
        $var = $request->getParsedBody();
        foreach ($var as $k => $v) {
            $var[$k] = trim($v);
        }

        $addFile = $this->settings['root_dir'] . 'var/gitbook.add';
        if (file_put_contents($addFile, implode('-_-', $var) . PHP_EOL, FILE_APPEND)) {
            $return = '<h2 style="text-align:center;">添加成功，请等待审核通过，谢谢您的支持!</h2><h3 style="text-align: center;"><a href="/">返回</a></h3>';
        }

        $body = $response->getBody();
        $body->write($return);
        return $response;
    }


    private function getMain($page, $limit)
    {
        $booksData = $this->getBooksData($page, $limit);
        return $this->phpRenderer->fetch('home/main.phtml', ['data' => $booksData, 'query' => $this->query]);
    }

    private function getPage($link, $total, $page, $limit)
    {
        $data = [];
        $totalPage = ceil($total / $limit);
        if ($total == 0) $is_last = true;
        else $is_last = ($totalPage == $page);
        $prev = '';
        $next = '';
        if ($page > 1) {
            $prev = $link . '&p=' . ($page - 1);
        }
        if (!$is_last) {
            $next = $link . '&p=' . ($page + 1);
        }
        $data['page'] = $page;
        $data['prev'] = $prev;
        $data['next'] = $next;
        $data['totalPage'] = $totalPage;
        return $this->phpRenderer->fetch('public/page.phtml', ['data' => $data]);
    }

    private function getBooksData($page, $limit): array
    {
        $booksData = [];
        $returnBooks = [];
        $total = 0;
        $rootDir = $this->settings['root_dir'];
        $booksDir = $rootDir . 'public/books/';

        if (!file_exists($booksDir)) {
            $this->logger->info('No books found');
            return $booksData;
        }
        $books = array_diff(scandir($booksDir), array('..', '.', '.git'));
        foreach ($books as $id => $book) {
            if (!is_dir($booksDir . $book)) {
                $this->logger->info('Not a book dir : ' . $booksDir . $book);
                continue;
            }
            $bookIndex = $booksDir . $book . '/index.html';
            if (!file_exists($bookIndex)) {
                $this->logger->info('No book json file :' . $bookIndex);
                return $booksData;
            }
            $thisBook = file_get_contents($bookIndex);

            $pattern = '|<title>(.*?)<|ism';
            preg_match_all($pattern, $thisBook, $matches, PREG_PATTERN_ORDER);
            $title = $matches[1][0] ?? '';
            $title = explode(' · ', $title)[1] ?? '';
            if ($this->query && (false === stripos($title, $this->query))) continue;

            $pattern = '|<meta name="author" content="(.*?)"|ism';
            preg_match_all($pattern, $thisBook, $matches, PREG_PATTERN_ORDER);
            $author = $matches[1][0] ?? '';

            $pattern = '|<section class="normal markdown-section">(.*?)<\/section>|ism';
            preg_match_all($pattern, $thisBook, $matches, PREG_PATTERN_ORDER);
            $description = $matches[1][0] ?? '';

            $booksData[] = [
                'id' => $id,
                'title' => $title,
                'description' => substr(strip_tags(preg_replace('|<h1(.*?)<\/h1>|ism', '', $description)), 0, 180) . '...',
                'author' => $author,
                'alias' => $book
            ];
            $total++;
        }
        $i = 0;
        $start = ($page - 1) * $limit;
        foreach ($booksData as $index => $book) {
            if ($index >= $start && $i < $limit) {
                $returnBooks[$index] = $book;
                $i++;
            }
        }
        $this->total = $total;
        return $returnBooks;
    }

}